# -*- coding: UTF-8 -*-
import datetime
import os
import traceback
from pathlib import Path

import pymongo
from flask import Flask, request, jsonify
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy,get_debug_queries
from core.dto.error import ErrorDTO
from log import register_logger
import sys, getopt

app = Flask(__name__)
'''跨域处理'''
CORS(app, supports_credentials=True)
env = 'prod'

if sys.argv[0].endswith("\\server.py") or sys.argv[0].endswith("/server.py"):
    #读取环境配置节
    argv = sys.argv[1:]
    #读取环境参数
    try:
        opts, args = getopt.getopt(argv, "e:", ["env="])
    except getopt.GetoptError:
        print('server.py -env <env_name> #env_name可为 dev/prod')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('server.py -env <env_name> #env_name可为 dev/prod')
            sys.exit()
        elif opt in ("-e"):
            env = arg


'''读取配置文件'''
if env == 'dev':
    #本地调试环境
    app.config.from_pyfile("./settings_dev.py", True)


elif env == 'prod':
    #线上生产环境
    app.config.from_pyfile("./settings_prod.py", True)

"""APP 合法性验证中间价"""
#app.db = SQLAlchemy(app)

@app.after_request
def close_request_session(response):
    """解决mysql server gone away"""
    #app.db.session.remove()
    return response


basedir = Path(__file__).parent  # 项目根目录
logdir = basedir.joinpath(r'logs')
if not logdir.is_dir():
    os.makedirs(logdir)

register_logger(app, logdir)


@app.errorhandler(Exception)
def catch_all_except(e):
    api_path = request.full_path
    api_method = request.method
    ip_addr = request.remote_addr
    try:
        request_data = request.get_json(force=True)
    except Exception as ex:
        request_data = request.form.to_dict()

    request_data = str(request_data)
    with open(logdir.joinpath('error.log'), 'a+', encoding="utf-8") as f:
        asctime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        f.write(
            asctime
            + " "
            + ip_addr
            + " "
            + api_method
            + " "
            + api_path
            + '->'
            + request_data
            + '\n exception ->'
            + str(e)
            + '\n'
            + traceback.format_exc()
            + '\n'
        )

    errorDTO = ErrorDTO()
    errorDTO.message = str(e)
    return jsonify(errorDTO), 403


@app.after_request
def response_logger(response):
    # 获取接口响应数据
    api_path = request.full_path
    api_method = request.method
    ip_addr = request.remote_addr
    # 获取接口请求数据
    try:
        request_data = request.get_json(force=True)
    except Exception as e:
        request_data = request.form.to_dict()

    request_data, response_data = str(request_data), str(response.json)

    with open(logdir.joinpath('runtime.log'), 'a+', encoding="utf-8") as f:
        asctime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        f.write(
            asctime
            + " "
            + ip_addr
            + " "
            + api_method
            + " "
            + api_path
            + '->'
            + request_data
            + '@response'
            + response_data
            + '\n'
        )
    return response


@app.after_request
def sql_logger(response):
    # 获取接口响应数据
    api_path = request.full_path
    api_method = request.method
    ip_addr = request.remote_addr
    # 获取接口请求数据
    try:
        request_data = request.get_json(force=True)
    except Exception as e:
        request_data = request.form.to_dict()

    request_data = str(request_data)

    with open(logdir.joinpath('sql.log'), 'a+', encoding="utf-8") as f:
        for query in get_debug_queries():
            sql = """Slow query: %s\n Parameters: %s\n Duration: %s\n Context: %s""" % (
                query.statement,
                query.parameters,
                query.duration,
                query.context,
            )
            asctime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            f.write(
                asctime
                + " "
                + ip_addr
                + " "
                + api_method
                + " "
                + api_path
                + '->'
                + request_data
                + '@sql'
                + sql
                + '\n'
            )
    return response

